package com.sharemarking.application.common.utils;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import org.springframework.beans.factory.annotation.Value;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

/**
 * 上传文件--阿里云oss
 * Created by cjw on 2017/11/25.
 */
public class OSSPutObject {
    //@Value("${oss.endpoint}")
    private static String endpoint = "oss-cn-qingdao.aliyuncs.com";

    //@Value("${oss.AccessKeyID}")
    private static String accessKeyId = "LTAIWTMz0dAgUlU8";

    //@Value("${oss.AccessKeySecret}")
    private static String accessKeySecret = "m37l9W9bdfQn6pNiIkmhOQ0zFRgFLC";

    //@Value("${oss.bucketName}")
    private static String bucketName = "testoss0";

    /**
     * 上传文件流
     * @param filePath
     * @param fileName
     * @throws Exception
     */
    public static void putFileStream(String filePath,String fileName) throws Exception {
        // 创建OSSClient实例
        System.out.println("=====putFileStream"+accessKeyId);
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流
        InputStream inputStream = new FileInputStream(filePath);
        ossClient.putObject(bucketName, fileName, inputStream);
        // 关闭client
        ossClient.shutdown();
    }
    /**
     * 上传文件流
     * @param inputStream
     * @param fileName
     * @throws Exception
     */
    public static void putFileInputStream(InputStream inputStream,String fileName) throws Exception {
        // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流
        ossClient.putObject(bucketName, fileName, inputStream);
        // 关闭client
        ossClient.shutdown();
    }
    /**
     * 上传网络流
     * @param fileUrl
     * @param fileName
     * @throws Exception
     */
    public static void putNetworkStream(String fileUrl,String fileName) throws Exception {
        // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 上传文件流
        InputStream inputStream = new URL(fileUrl).openStream();
        ossClient.putObject(bucketName, fileName, inputStream);
        // 关闭client
        ossClient.shutdown();
    }
    /**
     * 上传本地文件
     * @param filePath
     * @param fileName
     * @throws Exception
     */
    public static void putLocalFile(String filePath,String fileName) throws Exception {
        // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        ossClient.putObject(bucketName, fileName, new File(filePath));
        // 关闭client
        ossClient.shutdown();
    }

    /**
     * 断点续传上传文件
     * @param filePath
     * @param fileName
     * @param taskNum
     * @param partSize
     * @throws Exception
     */
    public static void uploadFile(String filePath,String fileName,int taskNum, long partSize) throws Exception {
        // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 设置断点续传请求
        UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, fileName);
        // 指定上传的本地文件
        uploadFileRequest.setUploadFile(filePath);
        // 指定上传并发线程数
        if(taskNum>1)
            uploadFileRequest.setTaskNum(taskNum);
        // 指定上传的分片大小1 * 1024 * 1024=1mb,int最大值：2147483647~=20*1024*1024*1=20mb
        if(partSize>100*1024&&partSize<5*1024*1024*1024) //从100KB到5GB
            uploadFileRequest.setPartSize(partSize);//单位是Byte,默认100K
        // 开启断点续传
        uploadFileRequest.setEnableCheckpoint(true);
        // 断点续传上传
        try {
            ossClient.uploadFile(uploadFileRequest);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        // 关闭client
        ossClient.shutdown();
    }
    /**
     * 断点下载文件
     * @param filePath
     * @param fileName
     * @param taskNum
     * @throws Exception
     */
    public static void downloadFile(String filePath,String fileName,int taskNum) throws Exception {
        // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 下载请求，10个任务并发下载，启动断点续传
        DownloadFileRequest downloadFileRequest = new DownloadFileRequest(bucketName, fileName);
        downloadFileRequest.setDownloadFile(filePath);
        downloadFileRequest.setTaskNum(taskNum);
        downloadFileRequest.setEnableCheckpoint(true);
        // 下载文件
        DownloadFileResult downloadRes = null;
        try {
            downloadRes = ossClient.downloadFile(downloadFileRequest);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        // 下载成功时，会返回文件的元信息
        downloadRes.getObjectMetadata();
        // 关闭client
        ossClient.shutdown();
    }

    /**
     * 下载到本地文件
     * @param filePath:具体到文件名
     * @param fileName
     * @throws IOException
     */
    public static void loadFileToLocal(String filePath,String fileName) throws IOException {
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        ossClient.getObject(new GetObjectRequest(bucketName, fileName), new File(filePath));
        ossClient.shutdown();
    }

    /**
     * 文件是否存在
     * @param fileName
     * @return
     */
    public static boolean doesObjectExist(String fileName){
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        boolean found = ossClient.doesObjectExist(bucketName, fileName);
        ossClient.shutdown();// 创建OSSClient实例
        return found;
    }

    /**
     * 删除单个文件
     * @param fileName
     */
    public static void deleteObject(String fileName){
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        ossClient.deleteObject(bucketName, fileName);
        ossClient.shutdown();
    }

    /**
     * 删除多个文件
     * @param keys
     * @return
     */
    public static List<String> deleteObjects(List<String> keys){
        // 创建OSSClient实例
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        /**
         * 每次最多删除1000个Object，并提供两种返回模式：详细(verbose)模式和简单(quiet)模式:
         * 详细模式(setQuiet(false))：返回的成功删除Object的结果，即DeleteObjectsResult.getDeletedObjects，默认模式；
         * 简单模式(setQuiet(true))：返回的删除过程中出错的Object结果，即DeleteObjectsResult.getDeletedObjects。
         */
        // 删除Objects
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName);
        deleteObjectsRequest.setQuiet(true);//简单模式
        deleteObjectsRequest.withKeys(keys);
        DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(deleteObjectsRequest);
        List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
        // 关闭client
        ossClient.shutdown();
        return deletedObjects;
    }

}
